<template>
  <div class="h100 oh rel" ref="map" id="group-map">
    <the-tool
        @back="$emit('update:viewPondId',null)"
        :currentPond="currentPond"
        v-if="cesiumMap"
        :cesium-map="cesiumMap"
        :recive-id="viewPondId"
        :pick-layers.sync="pickLayers"
    />
    <the-select v-if="cesiumMap && viewPondId" v-model="pickLayers" :monitorTypes="monitorTypes"/>
  </div>
</template>

<script>
import {initViewer} from "@/public/lib/map";
import {AppGlobalConfig, Cesium, wutu3d} from "@/public/global/const";
import {staticComputer} from "@/public/util/vue";
import CesiumEvent from "@/public/class/CesiumEvent";
import {FetchGetTailingLocation, FetchMonitorPointList} from "@/api";
import Vue from "vue";
import DivPint from "@/view/client/component/TheCesiumMap/component/DivPint";
import TheSelect from "@/view/client/component/TheCesiumMap/component/TheSelect";
import TheTool from "@/view/client/component/TheCesiumMap/component/TheTool";

export default {
  name: "TheCesiumMap",
  props: {
    viewPondId: [String, Number],
    dataPondId: [String, Number],
    monitorTypes: Array
  },
  components:{
    TheSelect,
    TheTool
  },
  watch:{
    viewPondId(){
      if(this.currentPond){
        this.jumpToPond()
      } else{
        this.$_init(false)
      }
    },
    dataPondId:{
      immediate:true,
      handler:'$_focusPond'
    },
    pickLayers(){
      const divPoints = this.divPoints;
      const len = divPoints.length;
      for (let i = 0; i < len; ++i) {
        const billboard = divPoints[i];
        billboard.visible = this.pickLayers.some(
            (item) => +item === billboard.monitorTypeId,
        );
      }
    },
  },
  data() {
    return {
      pickLayers: [],
      tailingLocations: []
    };
  },
  computed: {
    cesiumMap: staticComputer({}),
    waveDatasource: staticComputer({}),
    divPoints: staticComputer([]),
    tile3d: staticComputer(),
    map3d: staticComputer(),
    currentPond() {
      const pond = this.tailingLocations.find(item=> item.tailingPondId === this.viewPondId)
      if(!pond){
        return
      }
      let config3D = {}
      try {
        config3D = JSON.parse(pond.config3D)||config3D
      }catch (e){

      }
      return {
        ...pond,
        tileUrl: config3D.tileUrl,
        mapUrl: config3D.mapUrl,
        center: config3D.viewpoint || {
          y: pond.latitude,
          x: pond.longitude,
          z: 3000.0,
          heading: 0,
          pitch: -90,
          roll: 360,
        }
      }
    }
  },
  mounted() {
    const viewer = initViewer(this.$refs.map, false, {
      center: {
        "y": 21.263107,
        "x": 117.41503,
        "z": 870334.33,
        "heading": 0.3,
        "pitch": -54.9,
        "roll": 359.4
      },
    });
    viewer.scene.globe.depthTestAgainstTerrain = false;
    viewer.scene.terrainProvider = new Cesium.CesiumTerrainProvider({
      url: AppGlobalConfig.CesiumTerrainProvider,
    });
    viewer.imageryLayers.get(0).gamma = 0.8;
    viewer.wutu.openFlyAnimation(() => {
      this.$_focusPond()
    });
    this.cesiumMap = {
      viewer,
    };

    this.$_init();
    this.$emit('renderMap',this.cesiumMap)

    // get rendered tiles
    // viewer.camera.moveEnd.addEventListener(function() {
    //   var tilesToRender = viewer.scene.globe._surface._tilesToRender;
    //
    //   console.log(tilesToRender);
    // });
  },
  created() {
    window.closeDangerLabel = () => {
      if (this.label) {
        this.label.visible = false;
      }
    };
  },
  methods: {
    $_focusPond(){
      const val = this.dataPondId
      if(!val){
        return
      }
      const obj = this.waveDatasource.entities.getById(val)
      if(!obj){
        return
      }
      this.cesiumMap.viewer.selectedEntity = obj

      let props = obj.feature.properties;
      let coordinates = obj.feature.geometry.coordinates;
      let level =
          ["一", "二", "三", "四", "五", "六", "七", "八", "九"][
          props.level - 1
              ] || "一";
      const pos = obj.feature.geometry.coordinates;

      const position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1])
      const currentCameraView = this.cesiumMap.viewer.wutu.getCameraView()
      this.cesiumMap.viewer.wutu.centerPoint(
          position,
          {
            radius:currentCameraView.z,
            duration: 2,
            ...currentCameraView
          })


      const content = `
                            <table>
                                <tr><td>区域：</td><td>${props.areaName}</td></tr>
                                <tr><td>尾矿库：</td><td>${props.tailingName}</td></tr>
                                <tr><td>经纬度：</td><td>${coordinates[1]}N, ${coordinates[0]}E</td></tr>
                                <tr><td>等级：</td><td>${level}等</td></tr>
                            </table>
                        `;
      this.$_addLabel(position, "尾矿信息", content);
      // window.open(
      //     location.origin +
      //         this.$router.resolve({
      //             name: "Client",
      //         }).href,
      //     "_blank",
      // );
    },
    getViewPoint() {
      const viewer = this.cesiumMap.viewer;
      const center = this.Cartesian3_to_WGS84(viewer.camera.position);
      return {
        heading: viewer.camera.heading,
        roll: viewer.camera.roll,
        pitch: viewer.camera.pitch,
        x: center.x,
        y: center.y,
        z: center.z,
      };
    },
    Cartesian3_to_WGS84(point) {
      var cartesian33 = new Cesium.Cartesian3(point.x, point.y, point.z);
      var cartographic = Cesium.Cartographic.fromCartesian(cartesian33);
      var lat = Cesium.Math.toDegrees(cartographic.latitude);
      var lng = Cesium.Math.toDegrees(cartographic.longitude);
      var alt = cartographic.height;
      return {
        x: lng,
        y: lat,
        z: alt,
      };
    },
    jumpToPond() {
      if (this.label) {
        this.label.destroy();
        this.label=null
      }
      this.waveDatasource.show = false;
      this.cesiumMap.viewer.dataSources.remove(this.waveDatasource);
      this.cesiumMap.viewer.wutu.centerAt(this.currentPond.center)
      this.$_updateMonitorPointList()
      if(this.tile3d){
        this.cesiumMap.viewer.scene.primitives.remove(this.tile3d)
      }
      if(this.currentPond.tileUrl){
        this.tile3d = this.cesiumMap.viewer.scene.primitives.add(
            new Cesium.Cesium3DTileset({
              url:  this.$_getHttpUrl(this.currentPond.tileUrl),
              maximumScreenSpaceError: 32,
              maximumMemoryUsage: 2048,
            }),
        );
      }
      if(this.map3d){
        this.cesiumMap.viewer.imageryLayers.remove(this.map3d)
      }
      if(this.currentPond.mapUrl) {
        this.map3d = this.cesiumMap.viewer.imageryLayers.addImageryProvider(new Cesium.UrlTemplateImageryProvider({
          url: this.$_getHttpUrl(this.currentPond.mapUrl)
        }));
      }
    },
    $_getHttpUrl(url) {
      return url.startsWith('http') ? url : AppGlobalConfig.FRONT_URL + this.currentPond.mapUrl
    },
    async $_updateMonitorPointList() {
      const data = await FetchMonitorPointList({ id: this.viewPondId });
      this.divPoints = data.map(item=>{
        const position = Cesium.Cartesian3.fromDegrees(
            item.longitude,
            item.latitude,
            item.inith - 5 || 515,
        );
        const DivPintConstructor = Vue.extend(DivPint);
        const divPintInstance = new DivPintConstructor({});
        divPintInstance.info = item;
        divPintInstance.$mount(document.createElement("div"));

         const point = new wutu3d.DivPoint(this.cesiumMap.viewer, {
          html: divPintInstance.$el,
          anchor: [-16, 16],
          visible:  this.pickLayers.some((layer) => +layer === item.monitorTypeId),
          position,
          click:()=>{
            this.$emit('pointChange',item)
          }
        });
        point.monitorTypeId = item.monitorTypeId
        return point
      })
    },
    $_init(first = true) {
      if(!first){
        if(this.divPoints.length){
          this.divPoints.forEach((layer) =>{
            layer.destroy()
          })
        }
        this.cesiumMap.viewer.wutu.centerAt(
            {
              "y": 21.263107,
              "x": 117.41503,
              "z": 870334.33,
              "heading": 0.3,
              "pitch": -54.9,
              "roll": 359.4
            },
        )
      }
      this.waveDatasource = new Cesium.CustomDataSource("ds_effect");
      this.cesiumMap.viewer.dataSources.add(this.waveDatasource);
      const alarmIdx = -1;
      const eventHandler = new CesiumEvent({viewer: this.cesiumMap.viewer});
      FetchGetTailingLocation().then((tailingLocations) => {
        this.tailingLocations = tailingLocations
        const poiData = {
          type: "FeatureCollection",
          features: tailingLocations.map((tailingLocation) => {
            return {
              geometry: {
                coordinates: [tailingLocation.longitude, tailingLocation.latitude],
              },
              properties: {
                level: tailingLocation.levelId,
                areaName: tailingLocation.areaName,
                platformCode: tailingLocation.platformCode,
                tailingName:tailingLocation.tailingName,
                id: tailingLocation.tailingPondId,
                ...tailingLocation
              }
            }
          })
        };
        poiData.features.forEach((feature, index) => {
          const pos = feature.geometry.coordinates;
          const position = Cesium.Cartesian3.fromDegrees(pos[0], pos[1]);
          const obj = this.waveDatasource.entities.add({
            id: feature.properties.tailingPondId,
            position: position,
            billboard:{
              image: process.env.BASE_URL + "images/mount.png",
              position: Cesium.Cartesian3.fromDegrees(pos[0], pos[1]),
              width: 64,
              height: 64,
              color: Cesium.Color.fromCssColorString(
                  alarmIdx === index ? "#FF0000" : "#00FFFF",
              ),
              show: true,
            },
            ellipse: {
              height: 0.0,
              semiMinorAxis: 12000.0 * 2,
              semiMajorAxis: 12000.0 * 2,
              material: new wutu3d.CircleWaveMaterial({
                duration: 6000,
                color:
                    alarmIdx === index
                        ? Cesium.Color.fromCssColorString("rgba(255, 0,0,.2)")
                        : Cesium.Color.AQUA,
                gradient: 0.5,
                count: 2,
              }),
            },
            show: true,
          });
          obj.feature = feature;
          this.cesiumMap.waveDatasource = this.waveDatasource
          eventHandler.addListen(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, obj, (event) => {
            if (!obj || !obj.feature) return;
            this.$emit('update:viewPondId', feature.properties.id)
          })
          eventHandler.addListen(Cesium.ScreenSpaceEventType.LEFT_CLICK, obj, (event) => {
            if (!obj || !obj.feature) return;
            this.$emit('update:dataPondId', feature.properties.id)
          });
        });
      })

    },
    $_addLabel(position, title, content, className) {
      const viewer = this.cesiumMap.viewer;
      if (!viewer || !title || !content || !position) return;
      if (this.label) {
        this.label.destroy();
      }
      this.label = new wutu3d.DivPoint(viewer, {
        html: `<div  class="divpoint2 ${className ||
        ""}" style="display:none;width: 2rem;height: 160px;">
                    <div class="title" style="top:10px;left:.6rem;">${title}</div>
                    <div class="title-close" onclick="closeDangerLabel()"></div>
                    <div class="content" style="width: 1.25rem;left: .6rem;">${content}</div>
                  </div >`,
        anchor: [0, 120],
        position: position,
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(1000, 200000),//按视距距离显示
        // scaleByDistance: new Cesium.NearFarScalar(10000, 1.0, 100000, 0.1),
      });
      this.label.visible = true;
    },
  },
};
</script>

<style lang="scss">

</style>
